﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;

namespace GMMControl
{
    /// <summary>
    /// This class provides a reverse geocoding function.
    /// </summary>
    public class ReverseGeocoder
    {
        /// <summary>
        /// Given latitude e longitude of a point, the function returns the respective address (if available).
        /// The resolution of the address is to the street level, it means that it isn't in any case available
        /// the civic number nearest to the point.
        /// NOTE: This procedure uses the http://city.ask.com service.
        /// </summary>
        /// <param name="lat">Latitude</param>
        /// <param name="lon">Longitude</param>
        /// <returns>
        /// The relative address, if available;
        /// else an empty string.
        /// </returns>
        public static string Decode(double lat, double lon)
        {
            string url = "http://city.ask.com";

            HttpWebRequest req = (HttpWebRequest) WebRequest.Create(string.Format("{0}/rlook?ll={1}%2C{2}&r=m1",url,lat,lon));
            HttpWebResponse res = (HttpWebResponse) req.GetResponse();
            
            Stream receiveStream = res.GetResponseStream();
            StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
            string xml = readStream.ReadToEnd();
            res.Close();

            XDocument doc = XDocument.Parse(xml);
            string addr;
            try
            {
                addr = ((XElement)((XElement)doc.Root.FirstNode).FirstNode).Element(XName.Get("Match")).Element(XName.Get("Addr")).Value;

                for (int i = 0, n = addr.Length; i < n; i++)
                    if (Char.IsLetter(addr[i]))
                        return addr.Substring(i);
            }
            catch (NullReferenceException) { }
            
            return "";
        }
    }
}
